FFMPEG 3.4.2 | 您所在的位置:网站首页 › Android PageSnapHelper源码解析 › FFMPEG 3.4.2 |
1、数据结构之VideoState 如果引入新的变量重新表述: drift = s1 - c1,last_upt = c1, cur_time = c2,则新的等式如下: S2 = drift + c1 + (c2 - c1) * speed = drift + last_upt + ( cur_time - last_upt) * speed = drift + last_upt + (cur_time - last_upt) * (1 - (1 - speed) ) = drift + cur_time - (cur_time - last_upt)*(1 - speed)这就是ffplay中get_clock()函数使用的等式: double get_clock(Clock *c) { if (*c->queue_serial != c->serial) return NAN; if (c->paused) { return c->pts; } else { double time = av_gettime_relative() / 1000000.0; return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed); // 6、时间同步之refresh_loop_wait_event()前面说过,在ffplay早前的版本中,使用SDL_TimerThread提供的定时回调做同步,当前版本(ffmpeg 3.4)已经不再用了。现在的基本策略是:main_thread线程每隔0.01秒(定义为常量REFRESH_RATE)刷新一次显示。Frame delay以0.01的间隔减少,最后一段剩余时间会比0.01短,这时下一次刷新时间会不到0.01秒。按照正常24 frame/秒的频率,每frame的delay是0.042秒,所以0.01秒够短,不至于跳过某一个frame的显示。refresh_loop_wait_event() 大约每隔0.01秒调用一次video_refresh()。7、时间同步之video_refresh()Frame有一个serial整型成员。这个成员初始值为0,每次开始新video段时递增1,所以serial可以用来判断时间同步是否需要重新开始。用户调整播放位置时会开始新段,video初始播放时也会开始新段。Serial值由decoder设置。PacketQueue和FrameQueue也各有一个serial成员,标记Queue中最新packet/frame的serial。开始新段时调用decoder_start(),往PacketQueue中放入一个特殊的flush packet,并递增PacketQueue.serial。后面产生的packet会用新的serial标记。FrameQueue及其frame也同样处理。播放video有两种模式:一种是只管video stream的时钟就好了,不用与其他时钟同步,运行时带参数-sync video,如:ffplay -sync video avm.mp4另一种是video需要参考其他时钟,可能是audio stream的时钟,也可能是其他外部时钟,运行时指定-sync audio或-sync ext。-sync ext是默认选项。第一种模式下的逻辑很简单,用Clock就可以。但是ffplay没有用Clock。如果新段开始,则设置一个变量frame_timer记录当前时间;根据前后两个frame的pts差值,计算当前显示的frame的delay。如果frame没超时(current_time < frame_timer + delay),则继续显示当前frame,否则显示下一个frame;frame_timer累加delay。第二种的模式需要使用术语“master时钟”和“slave时钟”。video时钟是slave时钟,被参考的audio时钟或ext 时钟是master时钟。这种模式中,不但frame的delay要根据slave与master的差异再做修正,slave时钟本身也要修正。如果开始新段,则设置一个变量frame_timer记录当前时间;根据前后两个frame的pts差值计算当前显示的frame的delay。如果frame没超时(current_time < frame_timer + delay),则继续显示当前frame,否则显示下一个frame;比较Slave和Master,修正delay。如下图,如果本地时间为10000,并算出对应master的pts为100.0。Slave算出对应的pts可能落在如下区间。 a. (~, 100-delay),则slave播放落后了,所以要减少delay; b. (100-delay, 100+delay ),这是正常偏移,不做修正; c. (100+delay, 100.1),则slave超前了,所以要小幅增加delay; d. (100.1, ~),则slave太超前了,所以大幅增加delay。 frame_timer累加delay。根据当前frame的pts重置slave时钟。Frame_timer是一个与frame关联的累加量,而步骤h)可能丢弃frame,所以导致frame_timer值偏小。如果偏差太大,则将frame_timer修正到本地时间。调整后的delay和framer_timer可能导致连续的frame超时。这时应该跳过前面的frame,只显示最后一个frame。从两种模式的分析看,ffplay的frame_timer没有考虑speed,所以它不支持快进和慢进!后一种模式用了Clock修正slave与master的差异,也不影响frame_timer的speed特性。从Show_help_default()的选项看,ffplay的播放控制操作也没有快进慢进控制。+下图是video_refresh的流程图: 这个函数涉及到一个一般碰不到的主题: aspect ratio DAR = SAR × PAR*DAR = Display Aspect Ratio, SAR = Storage Aspect Ratio, PAR = Pixel Aspect Ratio 详细信息可以参考: https://en.wikipedia.org/wiki/Aspect_ratio_(image) Distinctions Further information: Pixel aspect ratio This article primarily addresses the aspect ratio of images as displayed, which is more formally referred to as the display aspect ratio (DAR). In digital images, there is a distinction with the storage aspect ratio (SAR), which is the ratio of pixel dimensions. If an image is displayed with square pixels, then these ratios agree; if not, then non-square, "rectangular" pixels are used, and these ratios disagree. The aspect ratio of the pixels themselves is known as the pixel aspect ratio (PAR) – for square pixels this is 1:1 – and these are related by the identity: SAR × PAR = DAR.Rearranging (solving for PAR) yields: PAR = DAR/SAR.For example, a 640 × 480 VGA image has a SAR of 640/480 = 4:3, and if displayed on a 4:3 display (DAR = 4:3), has square pixels, hence a PAR of 1:1. By contrast, a 720 × 576 D-1 PAL image has a SAR of 720/576 = 5:4, but is displayed on a 4:3 display (DAR = 4:3), so by this formula it would have a PAR of (4:3)/(5:4) = 16:15. However, because standard definition digital video was originally based on digitally sampling analog television, the 720 horizontal pixels actually capture a slightly wider image to avoid loss of the original analog picture. In actual images, these extra pixels are often partly or entirely black, as only the center 704 horizontal pixels carry actual 4:3 or 16:9 image. Hence, the actual pixel aspect ratio for PAL video is a little different from that given by the formula, specifically 12:11 for PAL and 10:11 for NTSC. For consistency, the same effective pixel aspect ratios are used even for standard definition digital video originated in digital form rather than converted from analog. For more details refer to the main article. In analog images such as film there is no notion of pixel, nor notion of SAR or PAR, and "aspect ratio" refers unambiguously to DAR. Actual displays do not generally have non-square pixels, though digital sensors might; they are rather a mathematical abstraction used in resampling images to convert between resolutions. Non-square pixels arise often in early digital TV standards, related to digitalization of analog TV signals – whose horizontal and vertical resolutions differ and are thus best described by non-square pixels – and also in some digital videocameras and computer display modes, such as Color Graphics Adapter (CGA). Today they arise particularly in transcoding between resolutions with different SARs. DAR is also known as image aspect ratio and picture aspect ratio, though the latter can be confused with pixel aspect ratio. 9、相关链接FFMPEG 3.4.2 - ffmpeg源代码分析 (一) FFMPEG 3.4.2 - ffmpeg源代码分析 (二) FFMPEG 3.4.2 - ffmpeg源代码分析 (三) FFMPEG 3.4.2 - ffmpeg源代码分析 (四)- x264 FFMPEG 3.4.2 - ffplay源代码分析 (一) FFMPEG 3.4.2 - ffplay源代码分析 (二) FFMPEG 3.4.2 - ffplay源代码分析 (三) 原文链接:https://www.jianshu.com/p/9dda5e5649c0 |
CopyRight 2018-2019 实验室设备网 版权所有 |